package com.ctshk.rpc.certificate.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.certificate.dto.AppointmentRoadTripDTO;
import com.ctshk.rpc.certificate.dto.CertificateAcceptDTO;
import com.ctshk.rpc.certificate.dto.CertificateRoadTripDTO;
import com.ctshk.rpc.certificate.entity.CertificateRoadTrip;
import com.ctshk.rpc.certificate.mapper.CertificateBusinessMapper;
import com.ctshk.rpc.certificate.mapper.CertificateRoadTripMapper;
import com.ctshk.rpc.certificate.req.CertificateAcceptPageReq;
import com.ctshk.rpc.certificate.req.CertificateRoadTripReq;
import com.ctshk.rpc.certificate.req.ProcCommonCertificateReq;
import com.ctshk.rpc.certificate.req.QueryRoadTripInfoReq;
import com.ctshk.rpc.certificate.service.ICertificateRoadTripService;
import com.ctshk.rpc.certificate.utils.OrderUtil;
import com.ctshk.rpc.system.service.IValidateService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 处理换领广东省自驾游 服务实现类
 * </p>
 *
 * @author 谢诗宏
 * @since 2021-03-25
 */
@DubboService
public class CertificateRoadTripServiceImpl extends ServiceImpl<CertificateRoadTripMapper, CertificateRoadTrip> implements ICertificateRoadTripService {

    @Autowired
    private CertificateRoadTripMapper roadTripMapper;

    @Autowired
    private CertificateBusinessMapper businessMapper;

    @DubboReference
    private IValidateService validateService;

    @Override
    public Result saveRoadTrip(CertificateRoadTripReq certificateRoadTripReq, Long userId) {
        if (userId == null) {
            return Result.failed(SystemError.USER_1000);
        }
        if (certificateRoadTripReq == null) {
            return Result.failed(SystemError.SYS_416);
        }

        // 有id保存
        CertificateRoadTrip certificateRoadTrip;
        if (null != certificateRoadTripReq.getId()) {
            certificateRoadTrip = roadTripMapper.selectById(certificateRoadTripReq.getId());
            if (Objects.isNull(certificateRoadTrip)) {
                return Result.failed(SystemError.SYS_411);
            }
            BeanUtils.copyProperties(certificateRoadTripReq, certificateRoadTrip);
            certificateRoadTrip.setModifiedId(userId);
            certificateRoadTrip.setGmtModified(LocalDateTime.now());
            roadTripMapper.updateById(certificateRoadTrip);
        } else {
            // 保存预约单据
            certificateRoadTrip = new CertificateRoadTrip();
            BeanUtils.copyProperties(certificateRoadTripReq, certificateRoadTrip);
            Long permitId = SnowflakeIdWorker.nextId();
            certificateRoadTrip.setId(permitId);
            String registerNumber = OrderUtil.getReentryPermitRegisterNumber();
            certificateRoadTrip.setRegisterNumber(registerNumber);
            certificateRoadTrip.setCreateId(userId);
            certificateRoadTrip.setGmtCreate(LocalDateTime.now());
            certificateRoadTrip.setAcceptStatus(1);
            certificateRoadTrip.setIsDeleted(0);
            roadTripMapper.insert(certificateRoadTrip);
        }

        // 预约办证中心
        if (certificateRoadTrip.getSubmissionStatus() == 1) {
            Long res = businessMapper.reserveReentryPermit(certificateRoadTripReq.getName(), certificateRoadTripReq.getBusinessHallId(),
                    certificateRoadTripReq.getReserveDate(), certificateRoadTripReq.getReserveTime());
            if (res != 1) {
                return Result.failed(new BusinessException(SystemError.CERTIFICATE_BUSINESS_16002));
            }
        }
        return Result.success(certificateRoadTrip.getId());
    }

    @Override
    public CertificateRoadTripDTO queryDetail(Long id) {
        CertificateRoadTrip certificateRoadTrip = roadTripMapper.selectById(id);
        if (Objects.isNull(certificateRoadTrip)) {
            throw new BusinessException(SystemError.SYS_411);
        }
        CertificateRoadTripDTO tripDTO = new CertificateRoadTripDTO();
        BeanUtils.copyProperties(certificateRoadTrip, tripDTO);
        return tripDTO;
    }

    @Override
    public Result updateRoadTrip(CertificateRoadTripReq certificateRoadTripReq, Long userId) {
        if (userId == null) {
            return Result.failed(SystemError.USER_1000);
        }
        if (certificateRoadTripReq == null) {
            return Result.failed(SystemError.SYS_416);
        }
        CertificateRoadTrip certificateRoadTrip = roadTripMapper.selectById(certificateRoadTripReq.getId());
        if (Objects.isNull(certificateRoadTrip)) {
            return Result.failed(SystemError.SYS_411);
        }
        BeanUtils.copyProperties(certificateRoadTripReq, certificateRoadTrip);
        certificateRoadTrip.setModifiedId(userId);
        certificateRoadTrip.setGmtModified(LocalDateTime.now());
        roadTripMapper.updateById(certificateRoadTrip);
        return Result.success();
    }

    @Override
    public Result procReserveRoadTrip(ProcCommonCertificateReq procCommonCertificateReq, Long userId) {
        if (userId == null) {
            return Result.failed(SystemError.USER_1000);
        }
        if (procCommonCertificateReq == null) {
            return Result.failed(SystemError.SYS_416);
        }
        CertificateRoadTrip certificateRoadTrip = roadTripMapper.selectById(procCommonCertificateReq.getId());
        if (Objects.isNull(certificateRoadTrip)) {
            return Result.failed(SystemError.SYS_411);
        }
        certificateRoadTrip.setAcceptStatus(procCommonCertificateReq.getAcceptStatus());
        certificateRoadTrip.setModifiedId(userId);
        certificateRoadTrip.setGmtModified(LocalDateTime.now());
        certificateRoadTrip.setAcceptDesc(procCommonCertificateReq.getAcceptDesc());
        roadTripMapper.updateById(certificateRoadTrip);
        return Result.success();
    }

    @Override
    public PageResponse<CertificateAcceptDTO> queryCertificateAcceptList(CertificateAcceptPageReq req) {
        Page<CertificateRoadTrip> certificatePage = new Page<>(req.getPageNo(), req.getPageSize());
        QueryWrapper<CertificateRoadTrip> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(null != req.getApplyTypeId(), CertificateRoadTrip::getApplyTypeId, req.getApplyTypeId());
        queryWrapper.lambda().like(StringUtils.isNotBlank(req.getPhoneNum()), CertificateRoadTrip::getPhoneNum, req.getPhoneNum());
        queryWrapper.lambda().like(StringUtils.isNotBlank(req.getEmail()), CertificateRoadTrip::getEmail, req.getEmail());
        queryWrapper.lambda().eq(null != req.getAcceptStatus(), CertificateRoadTrip::getAcceptStatus, req.getAcceptStatus());

        // 处理时间区间不包括右边界问题
        if (null != req.getGmtCreateEnd()) {
            req.setGmtCreateEnd(req.getGmtCreateEnd().plusDays(1));
        }
        queryWrapper.lambda().between((null != req.getGmtCreateBegin() && null != req.getGmtCreateEnd()), CertificateRoadTrip::getGmtCreate,req.getGmtCreateBegin(),req.getGmtCreateEnd());
        Page<CertificateRoadTrip> iPage = roadTripMapper.selectPage(certificatePage, queryWrapper);
        List<CertificateRoadTrip> records = iPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
        }
        List<CertificateAcceptDTO> certificateAcceptQueryDTOList = EntityUtil.copyList(records, CertificateAcceptDTO.class);
        certificateAcceptQueryDTOList.forEach(record -> record.setCnName("-"));
        return new PageResponse<>(certificateAcceptQueryDTOList, iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }

    @Override
    public Result<AppointmentRoadTripDTO> queryAppointmentInfo(@Valid QueryRoadTripInfoReq queryAppointmentInfoReq, Long userId) {
        if (userId == null) {
            return Result.failed(SystemError.USER_1000);
        }
        validateService.check(queryAppointmentInfoReq.getKey(), queryAppointmentInfoReq.getCode());
        CertificateRoadTrip roadTrip = roadTripMapper.selectOne(new QueryWrapper<CertificateRoadTrip>().lambda()
                .eq(null != queryAppointmentInfoReq.getId(), CertificateRoadTrip::getId, queryAppointmentInfoReq.getId())
                .eq(StringUtils.isNotBlank(queryAppointmentInfoReq.getCertificateNo()), CertificateRoadTrip::getCertificateNo,queryAppointmentInfoReq.getCertificateNo())
                .eq(StringUtils.isNotBlank(queryAppointmentInfoReq.getRegisterNumber()), CertificateRoadTrip::getRegisterNumber,queryAppointmentInfoReq.getRegisterNumber())
                .eq(StringUtils.isNotBlank(queryAppointmentInfoReq.getReferenceNumber()), CertificateRoadTrip::getReferenceNumber,queryAppointmentInfoReq.getReferenceNumber())
                .eq(StringUtils.isNotBlank(queryAppointmentInfoReq.getPlateNumber()), CertificateRoadTrip::getPlateNumber,queryAppointmentInfoReq.getPlateNumber()));

        AppointmentRoadTripDTO appointmentInfoDTO = new AppointmentRoadTripDTO();
        BeanUtils.copyProperties(roadTrip, appointmentInfoDTO);
        return Result.success(appointmentInfoDTO);
    }

    @Override
    public Result cancelAppointment(Long id, Long userId) {
        CertificateRoadTrip roadTrip = roadTripMapper.selectById(id);
        if (Objects.isNull(roadTrip)) {
            return Result.failed(SystemError.SYS_411);
        }
        roadTrip.setAcceptStatus(0);
        roadTripMapper.updateById(roadTrip);
        return Result.success(roadTrip.getRegisterNumber());
    }
}
